package com.card.game;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

public class JinUtils {
	public static ImmutableList<List<Integer>> All3Cards = ImmutableList.copyOf(getAll3Cards(true));
	public static ImmutableList<List<Integer>> All2Cards = ImmutableList.copyOf(getAll2Cards(true));
	public static ImmutableList<Integer> AllCards = ImmutableList.copyOf(getAllCard(true));
	public static ImmutableList<List<Integer>> NoFengAll3Cards = ImmutableList.copyOf(getAll3Cards(false));
	public static ImmutableList<List<Integer>> NoFengAll2Cards = ImmutableList.copyOf(getAll2Cards(false));
	public static ImmutableList<Integer> NoFengAllCards = ImmutableList.copyOf(getAllCard(false));
//	public static ImmutableList<List<Integer>> All4Cards = ImmutableList.copyOf(getAll4Cards(true));
//	public static ImmutableList<List<Integer>> All5Cards = ImmutableList.copyOf(getAll5Cards(true));
//	public static ImmutableList<List<Integer>> All6Cards = ImmutableList.copyOf(getAll6Cards(true));

	
	private static List<Integer> getAllCard(boolean haveFeng) {
		List<Integer> cc = Lists.newArrayList();
		for (int i = CardType.WAN; i <= CardType.BING; i++) {
			for (int j = 1; j < 10; j++) {
				Card c = new Card(i, j);
				cc.add(c.getMm());
			}
		}
		if(haveFeng) {
			for (int i = CardType.DONG; i <= CardType.BAI; i++) {
				Card c = new Card(i, 0);
				cc.add(c.getMm());
			}
		}
		return cc;
	}
	
	public static List<List<Integer>> getAll2Cards(boolean haveFeng) {
		if(AllCards == null) {
			AllCards = ImmutableList.copyOf(getAllCard(haveFeng));
		}
		List<List<Integer>> all2Cards = Lists.newArrayList();
		for (int card : AllCards) {
			for (int c2 : AllCards) {
				List<Integer> temp = Lists.newArrayList(card);
				temp.add(c2);
				Collections.sort(temp);
				if(!all2Cards.contains(temp)) {
					all2Cards.add(temp);
				}
			}
		}
		return all2Cards;
	}
	public static List<List<Integer>> getAll3Cards(boolean haveFeng) {
		if(AllCards == null) {
			AllCards = ImmutableList.copyOf(getAllCard(haveFeng));
		}
		List<List<Integer>> all2Cards = Lists.newArrayList();
		for (int c1 : AllCards) {
			for (int c2 : AllCards) {
				for (int c3 : AllCards) {
					List<Integer> temp = Lists.newArrayList(c1,c2,c3);
					Collections.sort(temp);
					if(!all2Cards.contains(temp)) {
						all2Cards.add(temp);
					}
				}
			}
		}
		System.err.println(all2Cards.size());
		return all2Cards;
	}
	
	public static List<List<Integer>> getAll4Cards(boolean haveFeng) {
		if(AllCards == null) {
			AllCards = ImmutableList.copyOf(getAllCard(haveFeng));
		}
		List<List<Integer>> all2Cards = Lists.newArrayList();
		for (int c4 : AllCards) {
			for (List<Integer> list : All3Cards) {
				List<Integer> temp = Lists.newArrayList(list);
				temp.add(c4);
				Collections.sort(temp);
				all2Cards.add(temp);
			}
		}
		Set<List<Integer>> tempList = Sets.newHashSet(all2Cards);
		System.err.println("jin4:"+tempList.size());
		return Lists.newArrayList(tempList);
	}
	
	public static List<Card> getTingCards(Vector<Card> sours,Card jinCard,boolean haveFeng) {
		Vector<Card> clones = (Vector<Card>)sours.clone();
		List<Card> jinCards = QzUtils.getSameCard(clones, jinCard);
		clones.removeAll(jinCards);
		int size = jinCards.size();
//		if(size >= 4) {
//			return Lists.newArrayList(getFinalAllCard(haveFeng));
//		}
		List<Integer> cards = MMHandUtils.transInteger(clones);
		List<Integer> tingCards = null;
		if(size == 0) {
			tingCards = getTing0(cards, jinCard, haveFeng);
		}else if(size == 1) {
			tingCards = getTing1(cards, jinCard, haveFeng);
		}else if(size == 2) {
			tingCards = getTing2(cards, jinCard, haveFeng);
		}else if(size == 3) {
			tingCards = getTing3(cards, jinCard, haveFeng);
		}
		List<Card> tts = Lists.newArrayList();
		if(tingCards != null && !tingCards.isEmpty()) {
			for (int card : tingCards) {
				tts.add(Card.transCard(card));
			}
		}
		if(tts != null && !tts.isEmpty()) {
			tts.remove(jinCard);
			tts.add(jinCard);
		}
		return tts;
	}
	
	private static ImmutableList<Integer> getFinalAllCard(boolean haveFeng) {
		if(haveFeng) {
			return JinUtils.AllCards;
		}else{
			return JinUtils.NoFengAllCards;
		}
	}
	
	private static List<Integer> getTing0(List<Integer> sours,Card jinCard,boolean haveFeng) {
		List<Integer> tingCards = Lists.newArrayList();
		ImmutableList<Integer> allCards = getFinalAllCard(haveFeng);
		for (int card : allCards) {
			List<Integer> cards = Lists.newArrayList(sours);
			cards.add(card);
			if(MMHandUtils.isHuPai(cards)) {
				tingCards.add(card);
			}
		}
		return tingCards;
	}
	
	private static List<Integer> getTing1(List<Integer> sours,Card jinCard,boolean haveFeng) {
		List<Integer> tingCards = Lists.newArrayList();
		for (int temp : getFinalAllCard(haveFeng)) {
			ImmutableList<Integer> allCards = getFinalAllCard(haveFeng);
			for (int card : allCards) {
				List<Integer> cards = Lists.newArrayList(sours);
				cards.add(card);
				if(QzUtils.isHu(cards, temp)) {
					tingCards.add(temp);
					break;
				}
			}
		}
		return tingCards;
	}
	
	private static List<Integer> getTing2(List<Integer> sours,Card jinCard,boolean haveFeng) {
		List<Integer> tingCards = Lists.newArrayList();
		ImmutableList<List<Integer>> all = JinUtils.NoFengAll2Cards;
		if(haveFeng) {
			all = JinUtils.All2Cards;
		}
		for (int temp : getFinalAllCard(haveFeng)) {
			for (List<Integer> cardList : all) {
				List<Integer> cards = Lists.newArrayList(sours);
				cards.addAll(cardList);
				if(QzUtils.isHu(cards, temp)) {
					tingCards.add(temp);
					break;
				}
			}
		}
		return tingCards;
	}
	
	private static List<Integer> getTing3(List<Integer> sours,Card jinCard,boolean haveFeng) {
		List<Integer> tingCards = Lists.newArrayList();
		ImmutableList<List<Integer>> all = JinUtils.NoFengAll3Cards;
		if(haveFeng) {
			all = JinUtils.All3Cards;
		}
		for (int temp : getFinalAllCard(haveFeng)) {
			for (List<Integer> cardList : all) {
				List<Integer> cards = Lists.newArrayList(sours);
				cards.addAll(cardList);
				if(QzUtils.isHu(cards, temp)) {
					tingCards.add(temp);
					break;
				}
			}
		}
		return tingCards;
	}
	
	public static void main(String[] args) {
//		boolean haveFeng = false;
//		Card jinCard = new Card(1, 5);
//		String cardsStr =  "3-1;1-5;1-1;2-1;2-1;1-5;1-5;";
//		Vector<Integer> sours = QzUtils.testCard(cardsStr);
//		long now = System.currentTimeMillis();
//		List<Integer> tingCards = getTingCards(sours, jinCard, haveFeng);
//		System.err.println(tingCards);
//		System.err.println("时间："+(System.currentTimeMillis()-now));
	}
}
